package com.luo.d3s.light.jpa.ec.application.assembler;

import com.luo.d3s.core.exception.ExceptionFactory;
import com.luo.d3s.light.jpa.ec.application.dto.command.OrderCreateCommand;
import com.luo.d3s.light.jpa.ec.application.dto.vo.OrderGoodsVo;
import com.luo.d3s.light.jpa.ec.application.dto.vo.OrderVo;
import com.luo.d3s.light.jpa.ec.domain.base.BizId;
import com.luo.d3s.light.jpa.ec.domain.base.Count;
import com.luo.d3s.light.jpa.ec.domain.base.Price;
import com.luo.d3s.light.jpa.ec.domain.order.model.Order;
import com.luo.d3s.light.jpa.ec.domain.order.model.OrderFactory;
import com.luo.d3s.light.jpa.ec.domain.order.model.OrderGoods;
import com.luo.d3s.light.jpa.ec.domain.order.model.ReceiveAddress;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Order转换器
 *
 * @author luohq
 * @date 2022-11-28 14:00
 */
public class OrderAssembler {

    /**
     * 转换创建订单Command为Order信息
     *
     * @param orderCreateCommand 创建订单Command
     * @return Order信息
     */
    public static Order createOrder(OrderCreateCommand orderCreateCommand) {
        //验证订单商品非空
        if (CollectionUtils.isEmpty(orderCreateCommand.getOrderGoods())) {
            throw ExceptionFactory.bizException("orderGoods is empty");
        }
        //预生成订单ID
        BizId orderId = BizId.newBizId();
        //转换单商品列表
        List<OrderGoods> orderGoodsList = orderCreateCommand.getOrderGoods().stream()
                .map(orderGoodsVo -> OrderFactory.createOrderGoods(
                        //商品ID
                        BizId.fromValue(orderGoodsVo.getGoodsId()),
                        //订单ID
                        orderId,
                        new Count(orderGoodsVo.getGoodsCount()),
                        new Price(orderGoodsVo.getGoodsPrice()),
                        new Price(orderGoodsVo.getGoodsSumPrice()))
                )
                .collect(Collectors.toList());
        //调用领域对象创建工厂OrderFactory.createOrder创建订单
        return OrderFactory.createOrder(
                orderId,
                new Price(orderCreateCommand.getOrderPrice()),
                new ReceiveAddress(orderCreateCommand.getReceiveAddress()),
                orderGoodsList);
    }

    /**
     * 转换Order信息为订单VO
     *
     * @param order Order信息
     * @return 订单VO
     */
    public static OrderVo toOrderVo(Order order) {
        if (null == order) {
            return null;
        }
        OrderVo orderVo = new OrderVo();
        List<OrderGoodsVo> orderGoodsVoList = Collections.emptyList();
        if (!CollectionUtils.isEmpty(order.getOrderGoods())) {
            orderGoodsVoList = order.getOrderGoods().stream().map(OrderAssembler::toOrderGoodsVo).collect(Collectors.toList());
        }
        orderVo.setOrderGoods(orderGoodsVoList);
        orderVo.setId(order.getId().getId());
        orderVo.setOrderPrice(order.getOrderPrice().getPrice());
        orderVo.setOrderStatus(order.getOrderStatus().getValue());
        orderVo.setCreateTime(order.getCreateTime());
        orderVo.setReceiveAddress(order.getReceiveAddress().getReceiveAddress());
        return orderVo;
    }

    /**
     * 转换Order信息为订单VO（不调用Order.getOrderGoods，避免JPA再次查询订单商品）
     *
     * @param order Order信息
     * @return 订单VO
     */
    public static OrderVo toOrderVoWithoutGoods(Order order) {
        if (null == order) {
            return null;
        }
        OrderVo orderVo = new OrderVo();
        List<OrderGoodsVo> orderGoodsVoList = Collections.emptyList();
        orderVo.setOrderGoods(orderGoodsVoList);
        orderVo.setId(order.getId().getId());
        orderVo.setOrderPrice(order.getOrderPrice().getPrice());
        orderVo.setOrderStatus(order.getOrderStatus().getValue());
        orderVo.setCreateTime(order.getCreateTime());
        orderVo.setReceiveAddress(order.getReceiveAddress().getReceiveAddress());
        return orderVo;
    }

    /**
     * 转换订单商品为VO
     *
     * @param orderGoods 订单商品信息
     * @return 订单商品信息VO
     */
    public static OrderGoodsVo toOrderGoodsVo(OrderGoods orderGoods) {
        OrderGoodsVo orderGoodsVo = new OrderGoodsVo();
        orderGoodsVo.setGoodsId(orderGoods.getGoodsId().getId());
        orderGoodsVo.setGoodsCount(orderGoods.getGoodsCount().getCount());
        orderGoodsVo.setGoodsPrice(orderGoods.getGoodsPrice().getPrice());
        orderGoodsVo.setGoodsSumPrice(orderGoods.getGoodsSumPrice().getPrice());
        return orderGoodsVo;
    }

}
